﻿package org.dm.utils
{
	import org.dm.utils.Iterator;
	
	/**
	 * ...
	 * @author Scott
	 */
	public class List
	{
		private var _head:Iterator = null;
		private var _tail:Iterator = null;
		private var _len:int = 0;
		
		public function List()
		{
		}
		
		public function get length() :int
		{ 
			return _len; 
		}
		
		public function empty():Boolean
		{
			return _len==0;
		}

		public function get front():*
		{
			return _head == null?null:_head.data;
		}
		
		public function get back():*
		{
			return _tail == null?null:_tail.data;
		}
		
		public function get first():Iterator
		{
			return _head == null?null:_head;
		}
		
		public function get last():Iterator
		{
			return _tail == null?null:_tail;
		}
		
		public function end():Iterator
		{
			return null;
		}
		
		public function clear():void
		{
			while(_len>0) pop_back();
		}
		
		public function push_back(data:*):void
		{
			var node:Iterator = new Iterator(data);
			
			if(_len==0)
			{
				_head = _tail = node;
			}
			else
			{
				_tail.next = node;
				_tail = node;
			}
			
			_len++;
		}
		
		public function push_front(data:*):void
		{
			var node:Iterator = new Iterator(data);
			
			if(_len==0)
			{
				_head = _tail = node;
			}
			else
			{
				_head.prev = node;
				_head = node;
			}
			
			_len++;
		}
		
		public function pop_back():void
		{
			if(_len==0) return;
			
			var tail:Iterator = _tail;
			
			if(_len>1)
			{
				var newtail:Iterator = _tail.prev;
				newtail.next = null;
				_tail = newtail;
			}
			else
			{
				_head = _tail = null;
			}
			
			_len--;
			tail.release();
		}
		
		public function pop_front():void
		{
			if(_len==0) return;
			
			var head:Iterator = _head;
			if(_len>1)
			{
				var newhead:Iterator = _head.next;
				newhead.prev = null;
				_head = newhead;
			}
			else
			{
				_head = _tail = null;
			}
			
			_len--;
			head.release();
		}
		
		public function erase(node:Iterator):Iterator
		{
			if(_len==0) return null;
			
			var iter:Iterator = _head;
			while(iter!=null)
			{
				if(iter===node)
				{
					if(_head===iter)
					{
						_head = iter.next;
					}
					
					if(_tail===iter)
					{
						_tail = iter.prev;
					}
					
					var next:Iterator = iter.next;
					iter.release();
					_len--;
					
					if(_len==0)
					{
						_head = _tail = null;
					}
					
					return next;
				}
				
				iter = iter.next;
			}
			
			return null;
		}
	}
}